// 子集为户型的数组合并
import React from 'react';
import styled from 'styled-components';
import _ from 'lodash';
import BaseTable from './src/index';

function getChildrenTree(nodes, predicate) {
  // 如果已经没有节点了，结束递归
  if (!(nodes && nodes.length)) {
    return [];
  }
  const newChildren = [];
  // eslint-disable-next-line no-restricted-syntax
  for (const node of nodes) {
    if (predicate(node)) {
      // 如果节点符合条件，直接加入新的节点集
      newChildren.push(node);
      node.children = getChildrenTree(node.children, predicate);
    } else {
      // 如果当前节点不符合条件，递归过滤子节点，
      // 把符合条件的子节点提升上来，并入新节点集
      newChildren.push(...getChildrenTree(node.children, predicate));
    }
  }
  return newChildren;
}

const GroupCell = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  &:not(:last-child) {
    border-right: 1px solid #eee;
  }
`;
const GroupRowCell = styled.div`
  display: flex;
  align-items: center;
  align-self: flex-start;
  justify-content: center;
  background: #f8f8f8;
  border-right: solid 1px #eee;
  &:not(:last-child) {
    border-right: 1px solid #eee;
  }
  z-index: 2;
`;

const getRow = (tree, level, deep) => {
  const columns = [];
  if (level <= deep) {
    tree.forEach(element => {
      // if (element.hidden !== true) {
      if (!(element.children && element.children.length > 0) || level === deep) {
        columns.push({
          ...element,
          level,
          children: null,
        });
      } else {
        const childColumns = getRow(element.children, level + 1, deep);
        columns.push(...childColumns);
      }
      // }
    });
  }
  return columns;
};

const calculateColspans = tree => {
  const x = tree;
  tree.forEach((element, index) => {
    if (element.children && element.children.length > 0) {
      calculateColspans(element.children);
      // 处理 colspan
      x[index].colspan = _.reduce(
        element.children,
        (sum, item) => sum + (item.colspan ? item.colspan : 0),
        0,
      );
    }
  });
};

const calculateStartEnd = columns => {
  const newColumns = [];
  columns.forEach(element => {
    const start = newColumns.length > 0 ? newColumns[newColumns.length - 1].end + 1 : 0;
    newColumns.push({
      ...element,
      start,
      end: start + element.colspan - 1,
    });
  });
  return newColumns;
};

const filterTree = tree => {
  const x = [];
  tree.forEach(element => {
    if (!element.hidden) {
      const y = {
        ...element,
      };
      delete y.children;
      if (element.children && element.children.length > 0) {
        const children = filterTree(element.children);
        if (children && children.length > 0) {
          y.children = children;
        }
      }
      x.push(y);
    }
  });
  return x;
};

const changeTreeBaseSpan = (tree, checkedValues) => {
  const x = [];
  tree.forEach(element => {
    const y = {
      ...element,
    };
    delete y.children;
    if (element.children && element.children.length > 0) {
      const children = changeTreeBaseSpan(element.children, checkedValues);
      if (children && children.length > 0) {
        y.children = children;
      }
    } else {
      y.colspan = y.attributes ? _.differenceWith(y.attributes, checkedValues).length : 1;
    }
    x.push(y);
  });
  return x;
};

function getHeaderRenderer(tree, rowLength = 3, renderComponent = () => {}) {
  const titleTree = filterTree(tree);
  calculateColspans(titleTree);
  const headerRenderer = ({ cells, columns, headerIndex }) => {
    let currentColumns = getRow(titleTree, 0, headerIndex);
    currentColumns = calculateStartEnd(currentColumns);
    if (headerIndex === rowLength) return cells;
    const groupCells = [];
    let width = 0;
    columns.forEach((column, columnIndex) => {
      if (column[BaseTable.PlaceholderKey]) {
        groupCells.push(cells[columnIndex]);
      } else {
        currentColumns.forEach((element, index) => {
          if (columnIndex >= element.start && columnIndex <= element.end) {
            const cellWidth = cells[columnIndex].props.style.width * 1;
            width += cellWidth;
            // console.log(element, columnIndex);
            // console.log(width, columnIndex);
          }
          if (columnIndex === element.end) {
            // console.log(tree, columns, cells, index, 'element.level');
            if (element.rowspan && headerIndex === element.level) {
              groupCells.push(
                <GroupRowCell
                  key={`header-group-cell-${element.key}`}
                  style={{
                    ...cells[columnIndex].props.style,
                    width,
                    marginTop: element.marginTop ? `${30 * element.marginTop}px` : 0,
                    height: `${30 * element.rowspan - 1}px`,
                  }}
                >
                  {/* todo */}
                  {headerIndex < rowLength ? (
                    <b style={{ fontSize: '12px' }}>
                      {columns[0].frozen === 'right' ? columns[0].title : element.name}
                    </b>
                  ) : columns[0].frozen === 'right' ? (
                    columns[0].title
                  ) : (
                    element.name
                  )}
                </GroupRowCell>,
              );
            } else if (element.isTabs) {
              groupCells.push(
                <GroupCell
                  key={`header-group-cell-${element.key}`}
                  style={{
                    ...cells[columnIndex].props.style,
                    width,
                    paddingLeft: '50px',
                    justifyContent: 'flex-start',
                    height: `${30 * element.rowspan - 1}px`,
                  }}
                >
                  {renderComponent()}{' '}
                </GroupCell>,
              );
            } else {
              groupCells.push(
                <GroupCell
                  key={`header-group-cell-${element.key}`}
                  style={{
                    ...cells[columnIndex].props.style,
                    width,
                    display: element.colspan ? 'inherit' : 'none',
                  }}
                >
                  {headerIndex < rowLength ? (
                    <b style={{ fontSize: '13px' }}>{element.name}</b>
                  ) : (
                    element.name
                  )}
                </GroupCell>,
              );
            }

            width = 0;
          }
        });
      }
    });
    return groupCells;
  };
  return headerRenderer;
}

function toThousands(num) {
  return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
}
const Statistic = props => {
  let result = '';
  result += props.prefix ? props.prefix : '';
  result += props.precision
    ? toThousands(_.round(props.value, props.precision).toString())
    : toThousands(props.value);
  result += props.suffix ? props.suffix : '';
  return result.toString();
};

const NumberView = props => {
  const { cellData } = props;
  let { precision } = props;
  let result = '';
  let valuex = [];
  if (_.isNumber(cellData) || _.isArray(cellData)) {
    if (_.isArray(cellData)) {
      valuex = cellData;
    } else {
      valuex.push(cellData);
    }
  }
  if (precision !== null) {
    precision = _.toNumber(precision);
  }
  const value = [];
  valuex.forEach(element => {
    if (element !== null) {
      const x = _.toNumber(element);
      value.push(_.toNumber(element ? x.toFixed(precision) : (0).toFixed(precision)));
    }
  });
  if (_.isArray(value) && value.length > 0) {
    value.forEach((element, index) => {
      if (index !== 0) {
        result += ' / ';
      }
      result += Statistic({
        ...props,
        value: element,
      });
    });
  }
  return result.toString();
};

const TextWithTags = props => {
  const value = props.cellData;
  let result = '';
  if (value.text && value.textFirst) {
    if (value.text === 'null') {
      result += '';
    } else {
      result += value.text;
    }
    result += '  ';
  }
  if ((_.isNumber(value.number) || _.isArray(value.number)) && value.textFirst) {
    result += NumberView({
      ...props,
      cellData: value.number,
    });
    result += '  ';
  }
  // 忽略tags
  // if (value.tags && value.tags.length > 0) {
  //   result += '<Tags cellData={value.tags} />';
  // }
  if (value.text && !value.textFirst) {
    result += value.text;
  }
  if ((_.isNumber(value.number) || _.isArray(value.number)) && !value.textFirst) {
    result += NumberView({
      ...props,
      cellData: value.number,
    });
  }
  return result.toString();
};

export default {
  getChildrenTree,
  getHeaderRenderer,
  getRow,
  changeTreeBaseSpan,
  calculate: {
    TextWithTags,
    NumberView,
    Statistic,
  },
};
